﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ServiceStack.Redis;

namespace Monitor.Repository.Regis
{
    public class CacheRegisClient : Models.Interfaces.ICacheClient
    {
        #region конструктор

        private string host = "localhost";

        private int port = 6379;

        private Models.Interfaces.ILogger _logger;

        public CacheRegisClient(Models.Interfaces.ILogger logger)
        {
            _logger = logger;
        }

        #endregion

        private string HeschFunc<T>(string key)
        {
            return typeof(T).FullName + "/" + key;
        }

        #region инициализация Initialize()

        public void Initialize()
        {
            try
            {
                using (RedisClient redisClient = new RedisClient(host, port))
                {
                    redisClient.FlushAll();
                }
            }
            catch (Exception e)
            {
                _logger.Fatal("CacheRegisClient - Initialize", e);
            }

        }

        #endregion

        #region добавление Add<T>(string key, T obj) Add<T>(string proptertyKey, IEnumerable<T> obj);

        #region добавление одного элемента
        public void Add<T>(string key, T obj)
        {
            try
            {
                using (RedisClient redisClient = new RedisClient(host, port))
                {
                    redisClient.Add(HeschFunc<T>(key), obj, TimeSpan.FromDays(1));
                }
            }
            catch (Exception e)
            {
                _logger.Fatal("CacheRegisClient - Add", e);
            }
        }
        #endregion

        #region добавление массива элементов

        public void Add<T>(string proptertyKey, IEnumerable<T> obj)
        {
            try
            {
                if (typeof(T).GetType().GetProperty(proptertyKey).CanRead)
                    using (RedisClient redisClient = new RedisClient(host, port))
                    {
                        foreach (T curObj in obj)
                        {
                            redisClient.Add(HeschFunc<T>(typeof(T).GetType().GetProperty(proptertyKey).GetValue(curObj).ToString()), curObj,
                                            TimeSpan.FromDays(1));
                        }
                    }
            }
            catch (Exception e)
            {
                _logger.Fatal("CacheRegisClient - Add", e);
            }
        }

        #endregion

        #endregion

        #region извлечение из кэша объекта по ключу  T GetById<T>(string key)

        public T GetById<T>(string key)
        {
            try
            {
                using (RedisClient redisClient = new RedisClient(host, port))
                {
                    return redisClient.Get<T>(this.HeschFunc<T>(key));
                }
            }
            catch (Exception e)
            {
                _logger.Fatal("CacheRegisClient - GetById - id:"+key, e);
            }
            return default(T);
        }

        #endregion


        #region MultiGet  IDictionary<string,T> GetByIds<T>(IEnumerable<string> keys)

        public List<T> GetByIds<T>(IEnumerable<string> keys)
        {
            List<T> result = new List<T>();
            try
            {
                using (RedisClient redisClient = new RedisClient(host, port))
                {
                    result = redisClient.GetAll<T>(keys.Select(HeschFunc<T>)).Select(n=>n.Value).ToList();
                }
            }
            catch (Exception e)
            {
                _logger.Fatal("CacheRegisClient - GetByIds:", e);
            }
            return result;
        }

        #endregion

        #region удаление элемента(-ов)  Delete<T>(string key), Delete<T>(string[] key)
        public void Delete<T>(string key)
        {
            try
            {
                using (RedisClient redisClient = new RedisClient(host, port))
                {
                    redisClient.Del(HeschFunc<T>(key));
                }
            }
            catch (Exception e)
            {
                _logger.Fatal("CacheRegisClient - Delete - key:" + key, e);
            }
        }
        public void Delete<T>(IEnumerable<string> key)
        {
            try
            {
                using (RedisClient redisClient = new RedisClient(host, port))
                {
                    redisClient.Del(key.Select(HeschFunc<T>).ToArray());
                }
            }
            catch (Exception e)
            {
                _logger.Fatal("CacheRegisClient - Delete - key:" + key, e);
            }
        }
        #endregion

        #region
        #endregion
        #region
        #endregion
        #region
        #endregion
        #region
        #endregion

    }

}